--- title: Mask visualization keywords: fastai sidebar: home_sidebar summary: "Visualize defects." description: "Visualize defects." nb_path: "nbs/02_masks.ipynb" ---
From an ImageId we get the pixel coordinates or the mask for every defect. Here an example of steel image.
img_id = "f383950e8.jpg"
tmp_df = train[train['ImageId'] == img_id]
img_path = train_path / img_id
im = Image.open(img_path)
print(tmp_df[["ImageId", "ClassId"]])
plt.figure(figsize=(15,5))
plt.xticks([]), plt.yticks([])
plt.imshow(im);
height, width = im.shape
height, width
assert height == 256
assert width == 1600
get_random_idx(50)
get_perm_imgs_path(train_pfiles, train_all)[:5]
item = train.iloc[1]
item_class_id = item["ClassId"]
item_rle = item["EncodedPixels"]
item_mask = rle2mask(item_rle, 1, (256,1600))
show_image(item_mask, figsize=(15,5));
img_name = "f383950e8.jpg"
row_df = train_multi.loc[train_multi["ImageId"] == img_name].iloc[0]
items = [0, img_name, (train_path / img_name), row_df]
masks = list(map(make_mask, items))
for imgid, mask in masks:
test_eq(type(imgid), str)
test_eq(mask.shape, (256, 1600, 4))
func = partial(make_mask, flatten=True)
masks = list(map(func, items))
for imgid, mask in masks:
test_eq(type(imgid), str)
test_eq(mask.shape, (256, 1600))
row_df
_, mask = make_mask(row_df)
_, flatten_mask = make_mask(row_df, flatten=True)
np.unique(mask), np.unique(flatten_mask)
rle = mask2rle(item_mask)
rle[:100]
test_eq(rle, item_rle)
fig, ax = plt.subplots(1, 4, figsize=(15, 5))
for i in range(4):
ax[i].axis('off')
ax[i].imshow(np.ones((50, 50, 3), dtype=np.uint8) * palet[i])
ax[i].set_title("class color: {}".format(i+1))
fig.suptitle("each class colors")
plt.show()
img_name = "f383950e8.jpg"
img = cv2.imread(str(train_path/img_name))
_, mask = make_mask(img_name)
plot_mask_image(img_name, img, mask)
mask[:, :, 1]
filter_mask = np.zeros((256, 1600, 4))
plt.imshow(filter_mask[:,:,2])
filter_mask[:, :, 2] = mask[:, :, 2]
plot_defected_image(img_path, class_id=4)
plot_defected_image(img_path, class_id=3)
plot_defected_image(img_path)
The ClassId = 1 identifies single and multiple defects in the form of rounded spots.
show_defects(class_id=1, n=20)
The ClassId = 2 identifies single and multiple defects of grooves.
show_defects(class_id=2, n=20)
The ClassId = 3 identifies single and multiple defects of scratches.
show_defects(class_id=3, n=20)
The ClassId = 4 identifies single and multiple defects of rolling process.
show_defects(class_id=4, n=20)
To select images with more than one defect:
show_defects(n=20, multi_defects=True)
To build masks for a segmentation model I followed two approaches:
1) As a first approach, I create the masks for all the images in the training folder. The masks are created with multi_rle_to_mask so with a Shape(256, 1600) and are saved in labels_path. This is useful to plot multi class masks and train with fast.ai DataLoaders.
2) Another approach is to create masks only with defect images and keep a Shape(256, 1600, 4). This is useful to pure Pytorch trainers.
NB: masks must be PNG files and not JPEG because JPEG's compression makes the labels get messed up occasionally (source).
masks = create_masks(train_multi)
ntraining = get_image_files(train_path)
test_eq(len(ntraining), len(masks))
idx = get_random_idx(len(masks))
im = np.array(Image.open(masks[idx[0]]))
plt.imshow(im);
classes=[0,1,2,3,4]
class_ids = np.unique(im).tolist()
check = [c in classes for c in class_ids]
assert False not in check